package cn.dao;

import cn.structure.*;
import cn.type.EntityTypeEnum;
import cn.type.RelTypeEnum;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;

/**
 * 数据访问对象接口
 *
 * @author Tao Lu
 */
public interface NeoDao {
    /**
     * 创建关系，关系由源节点指向目标节点
     *
     * @param source  源节点
     * @param target  目标节点
     * @param relType 关系类型
     */
    Relationship createRelation(Node source, Node target, RelTypeEnum relType);

    /**
     * 创建类节点
     *
     * @param tx     neo4j 事务实例
     * @param entity 类实体
     * @return 创建的节点
     */
    Node createClassNode(Transaction tx, ClassEntity entity);

    /**
     * 创建变量节点
     *
     * @param tx     neo4j 事务实例
     * @param entity 变量实体
     * @return 创建的节点
     */
    Node createVariableNode(Transaction tx, VariableEntity entity);

    /**
     * 创建类型变量节点
     *
     * @param tx     neo4j 事务实例
     * @param entity 类型变量的引用
     * @return 创建的节点
     */
    Node createTypeParameterNode(Transaction tx, TypeParameterEntity entity);

    /**
     * 创建方法节点
     *
     * @param tx     neo4j 事务实例
     * @param entity 方法实体
     * @return 创建的节点
     */
    Node createMethodNode(Transaction tx, MethodEntity entity);

    /**
     * 创建构造器节点
     *
     * @param tx     neo4j 事务实例
     * @param entity 构造器实体
     * @return 创建的节点
     */
    Node createConstructorNode(Transaction tx, ConstructorEntity entity);

    /**
     * 创建方法调用点节点
     *
     * @param tx     neo4j 事务实例
     * @param entity 调用点实体
     * @return 创建的节点
     */
    Node createInvocationNode(Transaction tx, InvocationEntity entity);

    /**
     * 创建构造器调用点节点
     *
     * @param tx     neo4j 事务实例
     * @param entity 调用点实体
     * @return 创建的节点
     */
    Node createConstructorCallNode(Transaction tx, ConstructorCallEntity entity);

    /**
     * 通过属性获取节点
     *
     * @param tx            neo4j 事务实例，事务外无法保存节点关系信息
     * @param property_name 属性名
     * @param property_val  属性值
     * @return 获取的节点
     */
    Node getNodeByProperty(Transaction tx, EntityTypeEnum entityType, String property_name, String property_val);

    Node getClassNodeByName(Transaction tx, String qualified_name);

    Node getMethodNodeBySignature(Transaction tx, String full_signature);

    Node getConstructorNodeBySignature(Transaction tx, String full_signature);

    Node getNodeByAstPath(Transaction tx, String entity_type, String ast_path);
}
